package com.guigu.aop;

import com.guigu.liuzhireng.pojo.Account;
import com.guigu.liuzhireng.pojo.Syslogs;
import com.guigu.liuzhireng.service.SyslogsService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import org.aspectj.lang.reflect.MethodSignature;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

//让spring进行扫描 一定要加
@Component
//告诉spring，这个一个切面类，里面可以定义切入点和通知
@Aspect
@Slf4j
public class SyslogsAdvice {

    @Autowired
    SyslogsService service;
    @Autowired
    HttpServletRequest request;

    //@annotation(com.guigu.aop.OpLog)

    /**`
     * 首先定义一个切点
     */
    @Pointcut("execution(* com.guigu.*.controller.*Controller.*(..))")
    public void printLog() {
    }

    @After("printLog()")
    public void after(JoinPoint joinPoint) throws Throwable {
        try{
        //获取方法名称
        String methodName = joinPoint.getSignature().getName();
        //获取类名称
        String className = joinPoint.getSignature().getDeclaringTypeName();
        // 从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取切入点所在的方法
        Method method = signature.getMethod();
        // 获取操作
        OpLog opLog = method.getAnnotation(OpLog.class);
        String msg = "模块名称:[{" + opLog.opModule() + "}],类型:[{" + opLog.operType() + "}],描述信息:[{" + opLog.operDesc() + "}]";
        //封装
        Syslogs syslogs = new Syslogs();
        syslogs.setSclass(className);//类名
        syslogs.setMethod(methodName); //方法名
        syslogs.setMsg(msg); //信息
        Account account = (Account) request.getSession().getAttribute("user");//用户名称
        if (account != null) {
            syslogs.setLoginid(account.getAccount());
        }
        service.insert(syslogs);
        //执行连接点的方法
       /* try {
            ((ProceedingJoinPoint) joinPoint).proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }*/
    } catch(Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}